/**
 * @file TcpServer.hpp
 * @author 1102403684@qq.com
 * @brief 
 * @version 0.1
 * @date 2024-10-16
 * 
 * @copyright Copyright (c) 2024
 * 
 */

#include <cstdint>
#include <unordered_map>


#include "Acceptor.hpp"
#include "EventLoop.hpp"
#include "LoopThreadPoll.hpp"
#include "Connection.hpp"
#include <signal.h>

class TcpServer
{
public:
    TcpServer(int port) : port_(port), next_id_(0), enable_inactive_release_(false), acceptor_(&baseloop_, port), pool_(&baseloop_)
    {
        acceptor_.set_accept_callback(std::bind(&TcpServer::new_connection, this, std::placeholders::_1));
        signal(SIGPIPE, SIG_IGN); //防止对面关闭服务器还在写时触发SIGPIPE异常关闭
    }

    void set_thread_count(int count){pool_.set_thread_count(count);}
    void set_connected_callback(const Connection::ConnectedCallBack &cb){connected_callback_ = cb;}
    void set_message_callback(const Connection::MessageCallBack &cb){message_callback_ = cb;}
    void set_closed_callback(const Connection::ClosedCallBack &cb){closed_callabck_ = cb;}
    void set_anyevent_callback(const Connection::AnyEventCallBack &cb){anyevent_callback_ = cb;}

    void enbale_inactive_release(int timeout){timeout_ = timeout; enable_inactive_release_ = true;}
    void run_task_after(const Functor& task, int delay){
        baseloop_.run_in_loop(std::bind(&TcpServer::run_task_after_in_loop,this, task, delay));
    }
    void start()
    {
        pool_.create(); //要在设置完工作线程数量后再创建！
        acceptor_.accept();
        baseloop_.start();
    }
private:
    void new_connection(int fd); //为新连接构造 Connection 进行管理
    void remove_connection(const Connection::PtrConnection& conn); //从conns_移除一个 Connection

    void remove_connection_in_loop(const Connection::PtrConnection& conn);

    void run_task_after_in_loop(const Functor& task, int delay)
    {
        next_id_++;
        baseloop_.add_timer(next_id_, delay, task);
    }


private:
    int port_; 
    uint64_t next_id_;  //定时任务id
    Acceptor acceptor_;
    EventLoop baseloop_; //负责监听事件的处理
    LoopThreadPoll pool_;//负责连接事件的处理

    std::unordered_map<uint64_t,Connection::PtrConnection> conns_;

    Connection::ConnectedCallBack connected_callback_;
    Connection::MessageCallBack message_callback_;
    Connection::ClosedCallBack closed_callabck_;
    Connection::ClosedCallBack server_closed_callabck_; //服务器内部的close回调
    Connection::AnyEventCallBack anyevent_callback_;

    int timeout_;//非活跃连接超时时间
    bool enable_inactive_release_;
};





void TcpServer::new_connection(int fd)
{
    next_id_++;
    Connection::PtrConnection conn ( new Connection(pool_.next_loop(),next_id_ ,fd) );
    conn->set_message_callback(message_callback_);
    conn->set_connected_callback(connected_callback_);
    conn->set_closed_callback(closed_callabck_);
    conn->set_anyevent_callback(anyevent_callback_);
    conn->set_server_closed_callback(std::bind(&TcpServer::remove_connection, this, std::placeholders::_1));
    if(enable_inactive_release_)
        conn->enable_inactive_release(timeout_);
    conn->established(); 

    conns_.insert(std::make_pair(next_id_, conn));
}



void TcpServer::remove_connection(const Connection::PtrConnection& conn)
{
    baseloop_.run_in_loop(std::bind(&TcpServer::remove_connection_in_loop,this, conn));
}

void TcpServer::remove_connection_in_loop(const Connection::PtrConnection& conn)
{
    int id = conn->get_connect_id();
    auto it = conns_.find(id);

    if(it != conns_.end()){
        conns_.erase(it);
    }
}
